"""
Copyright © 2021 Walkline Wang (https://walkline.wang)
Gitee: https://gitee.com/walkline/iot-explorer-sdk-for-micropython
"""
import hashlib
from ucryptolib import aes
import binascii


class Codec(object):
	class BASE64(object):
		@staticmethod
		def encode(encode_obj) -> bytes:
			return binascii.b2a_base64(encode_obj).replace(b'\n', b'')

		@staticmethod
		def decode(decode_str:str) -> bytes:
			if isinstance(decode_str, str):
				decode_str = decode_str.encode('utf-8')

			return binascii.a2b_base64(decode_str)

		@staticmethod
		def hexlify(bytes_obj:bytes) -> bytes:
			return binascii.hexlify(bytes_obj)


	class AES(object):
		MODE_ECB = 1
		MODE_CBC = 2
		MODE_CTR = 6

		@staticmethod
		def decrypt(encrypt_str, key, mode=MODE_CBC, init_vector=None):
			if isinstance(encrypt_str, str):
				encrypt_str = encrypt_str.encode('utf-8')
			
			if isinstance(key, str):
				key = key.encode('utf-8')
			
			if isinstance(init_vector, str):
				init_vector = init_vector.encode('utf-8')

			cipher = aes(key, mode, init_vector)
			decrypt_bytes = Codec.BASE64.decode(encrypt_str)

			return cipher.decrypt(decrypt_bytes)


	class HMAC(object):
		@staticmethod
		def sha1(key, message):
			if isinstance(key, str):
				key = key.encode('utf-8')
			
			if isinstance(message, str):
				message = message.encode('utf-8')

			SHA1_BLOCK_SIZE = 64
			KEY_BLOCK = key + (b'\0' * (SHA1_BLOCK_SIZE - len(key)))
			KEY_INNER = bytes((x ^ 0x36) for x in KEY_BLOCK)
			KEY_OUTER = bytes((x ^ 0x5C) for x in KEY_BLOCK)

			inner_message = KEY_INNER + message
			outer_message = KEY_OUTER + hashlib.sha1(inner_message).digest()

			return hashlib.sha1(outer_message).digest()
